package com.zbkj.service.util;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.aliyun.green20220302.Client;
import com.aliyun.green20220302.models.ImageModerationRequest;
import com.aliyun.green20220302.models.ImageModerationResponse;
import com.aliyun.green20220302.models.ImageModerationResponseBody;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyData;
import com.aliyun.green20220302.models.ImageModerationResponseBody.ImageModerationResponseBodyDataResult;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.zbkj.common.exception.CrmebException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 阿里内容审查工具类
 */
@Service
public class AlibabaContentModerationUtil {

    private static final Logger logger = LoggerFactory.getLogger(WeChatContentModerationUtil.class);

    //违规信息
    private static final Set<String> VIOLATION_LABELS = new HashSet<>(Arrays.asList(
            "pornographic_adultContent", "pornographic_adultContent_tii", "sexual_suggestiveContent",
            "sexual_partialNudity", "political_politicalFigure", "political_politicalFigure_name_tii",
            "political_politicalFigure_metaphor_tii", "political_TVLogo", "political_map", "political_outfit",
            "political_prohibitedPerson", "political_prohibitedPerson_tii", "political_taintedCelebrity",
            "political_taintedCelebrity_tii", "political_flag", "political_historicalNihility",
            "political_historicalNihility_tii", "political_religion_tii", "political_racism_tii", "political_badge", "violent_explosion", "violent_gunKnives", "violent_gunKnives_tii", "violent_armedForces", "violent_crowding", "violent_horrificContent", "violent_horrific_tii", "contraband_drug", "contraband_drug_tii", "contraband_gamble", "contraband_gamble_tii", "fraud_videoAbuse", "fraud_playerAbuse"
    ));

    @Value("${alibaba.toggle}")
    private String toggle;

    public void imageCheck(String imageUrl) {
        /**
         * 阿里云账号AccessKey拥有所有API的访问权限，建议您使用RAM用户进行API访问或日常运维。
         * 常见获取环境变量方式：
         * 方式一：
         *     获取RAM用户AccessKey ID：System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
         *     获取RAM用户AccessKey Secret：System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
         * 方式二：
         *     获取RAM用户AccessKey ID：System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_ID");
         *     获取RAM用户AccessKey Secret：System.getProperty("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
         */

        //判断内容审查开关是否开启
        if (toggle.equals("1")) {
            String accessKeyId = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID");
            String accessKeySecret = System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET");
            // 接入区域和地址请根据实际情况修改。
            ImageModerationResponse response = null;
            try {
                response = invokeFunction(accessKeyId, accessKeySecret, "green-cip.cn-shenzhen.aliyuncs.com", imageUrl);
                // 自动路由。
                if (response != null) {
                    //区域切换到cn-shanghai。
                    if (500 == response.getStatusCode() || (response.getBody() != null && 500 == (response.getBody().getCode()))) {
                        // 接入区域和地址请根据实际情况修改。
                        response = invokeFunction(accessKeyId, accessKeySecret, "green-cip.cn-shanghai.aliyuncs.com", imageUrl);
                    }
                }
            } catch (Exception e) {
                throw new CrmebException(StrUtil.format("阿里云内容审查失败,原因: errmsg = {}", e.getMessage()));

            }

            //参数校验
            if (response == null)
                throw new CrmebException("response not success. status:" + response.getStatusCode());
            if (response.getStatusCode() != 200)
                throw new CrmebException("服务器错误,StatusCode不等于200,请联系管理员!!!");
            ImageModerationResponseBody body = response.getBody();
            if (body.getCode() != 200)
                throw new CrmebException("服务器错误,Code不等于200,请联系管理员!!!");

            //判断返回的label是否包含违规信息
            ImageModerationResponseBodyData data = body.getData();
            List<ImageModerationResponseBodyDataResult> results = data.getResult();
            for (ImageModerationResponseBodyDataResult result : results) {
                if (VIOLATION_LABELS.contains(result.getLabel())) {
                    logger.error("上传的数据违规，没能通过阿里云审查，label: " + result.getLabel());
                    throw new CrmebException("上传的数据违规，拒绝发布");
                }
            }
        }
    }

    /**
     * 创建请求客户端
     *
     * @param accessKeyId
     * @param accessKeySecret
     * @param endpoint
     * @return
     * @throws Exception
     */
    public static Client createClient(String accessKeyId, String accessKeySecret, String endpoint) throws Exception {
        Config config = new Config();
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
        // 设置http代理。
        //config.setHttpProxy("http://10.10.xx.xx:xxxx");
        // 设置https代理。
        //config.setHttpsProxy("https://10.10.xx.xx:xxxx");
        // 接入区域和地址请根据实际情况修改
        // 接入地址列表：https://help.aliyun.com/document_detail/467828.html?#section-uib-qkw-0c8
        config.setEndpoint(endpoint);
        return new Client(config);
    }

    public static ImageModerationResponse invokeFunction(String accessKeyId, String accessKeySecret, String endpoint, String imageUrl) throws Exception {
        //注意，此处实例化的client请尽可能重复使用，避免重复建立连接，提升检测性能。
        Client client = createClient(accessKeyId, accessKeySecret, endpoint);

        // 创建RuntimeObject实例并设置运行参数
        RuntimeOptions runtime = new RuntimeOptions();

        // 检测参数构造。
        Map<String, String> serviceParameters = new HashMap<>();
        //公网可访问的URL。
        serviceParameters.put("imageUrl", imageUrl);
        //待检测数据唯一标识
        serviceParameters.put("dataId", UUID.randomUUID().toString());

        ImageModerationRequest request = new ImageModerationRequest();
        // 图片检测service：内容安全控制台图片增强版规则配置的serviceCode，示例：baselineCheck
        // 支持service请参考：https://help.aliyun.com/document_detail/467826.html?0#p-23b-o19-gff
        request.setService("baselineCheck");
        request.setServiceParameters(JSON.toJSONString(serviceParameters));

        ImageModerationResponse response = null;
        response = client.imageModerationWithOptions(request, runtime);
        return response;
    }
}
